package com.example.websocket;

import com.example.entity.SysCross;
import com.example.entity.User;
import com.example.service.CrossService;
import com.example.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.websocket.OnClose;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 加上RestController注解,使其可以响应文件上传链接
 * 如果不注册成控制层则必须加一个组件扫描，否则将无法注册
 * 所有的message都将使用json进行传输
 * 可以根据链接的直接得到roomName
 * 关于服务层的注入，只能通过Spring容器的上下文来进行赋值，否则会得到空值
 * ChatMessage为自己定义的进行信息传输的类，这里全部将其转为JSON，方便解析
 *
 * @author MDY
 */

@Component
@ServerEndpoint("/teamWebsocket/{userId}/{crossNumber}")
public class ConsultWebSocket {

    // 使用map来收集session，key为roomName，value为同一个房间的用户集合
    private static final Map<String, Set<Session>> rooms = new ConcurrentHashMap<>();
    //缓存session对应的用户
    private static final Map<String, String> users = new ConcurrentHashMap<>();


    private static CrossService crossService;

    private static UserService userService;

    @Autowired
    public void setCrossService(CrossService crossService) {
        ConsultWebSocket.crossService = crossService;
    }

    @Autowired
    public void setUserService(UserService userService) {
        ConsultWebSocket.userService = userService;
    }

    /**
     * 连接创建后将上线的用户广播给组员
     */
    @OnOpen
    public void connect(@PathParam("userId") Integer userId, @PathParam("crossNumber") String crossNumber, Session session) throws IOException {
//        System.out.println(userId+"<==========================================");


        // 将session按照房间名来存储，将各个房间的用户隔离
        if (!rooms.containsKey(crossNumber)) {
            // 创建房间不存在时，创建房间
            Set<Session> room = new HashSet<>();
            // 添加用户
            room.add(session);
            rooms.put(crossNumber, room);
        } else {
            // 房间已存在，直接添加用户到相应的房间
            rooms.get(crossNumber).add(session);
        }
        users.put(session.getId(), String.valueOf(userId));


    }

    @OnClose
    public void disConnect(@PathParam("userId") Integer userId, @PathParam("crossNumber") String crossNumber, Session session) {
        rooms.get(crossNumber).remove(session);
        users.remove(session.getId());
    }

    /**
     * @param msg 前台传回来的数据应为json数据
     */
    @OnMessage
    public void receiveMsg(@PathParam("userId") Integer userId, @PathParam("crossNumber") String crossNumber,
                           String msg, Session session) {
        // 此处应该有html过滤，进行数据加工
        msg = users.get(session.getId()) + ":" + msg;
        // 接收到信息后进行广播
        broadcast(crossNumber, msg);
    }


    // 按照房间名进行广播
    private void broadcast(String roomName, String msg) {
        rooms.get(roomName).forEach(s -> {
            try {
                s.getBasicRemote().sendText(msg);
            } catch (IOException e) {
                e.printStackTrace();
            }
        });
    }

}